package com.joinway.framework.data.jdbc.repository;

import groovy.sql.Sql;

import java.sql.Connection;
import java.util.ArrayList;
import java.util.List;

import javax.sql.DataSource;

import org.apache.commons.collections4.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class MultiDataSourceTableRepository extends TableRepository {

	private final static Logger log = LoggerFactory.getLogger(MultiDataSourceTableRepository.class);
	
	protected List<Sql> readOnlyClients = new ArrayList<>();
	
	protected List<DataSource> readOnlyDataSources;
	
	protected ThreadLocal<Integer> readOnlyIndex = new ThreadLocal<>();
	
	public MultiDataSourceTableRepository(DataSource readWriteDataSource) {
		super(readWriteDataSource);
		readOnlyDataSources = new ArrayList<>();
		readOnlyDataSources.add(readWriteDataSource);
		init(readOnlyDataSources);
	}

	public MultiDataSourceTableRepository(Connection connection) {
		super(connection);
		readOnlyClients.add(super.getSqlClient());
	}

	public MultiDataSourceTableRepository(DataSource readWriteDataSource, DataSource readOnlyDataSource) {
		super(readWriteDataSource);
		readOnlyDataSources = new ArrayList<>();
		readOnlyDataSources.add(readOnlyDataSource);
		init(readOnlyDataSources);
	}
	
	public MultiDataSourceTableRepository(DataSource readWriteDataSource, List<DataSource> readOnlyDataSources){
		super(readWriteDataSource);
		init(readOnlyDataSources);
	}
	
	public void useReadOnlyDataSource(int index){
		readOnlyIndex.set(index);
	}
	
	protected void init(List<DataSource> dataSources){
		if(CollectionUtils.isNotEmpty(dataSources)){
			this.readOnlyDataSources = dataSources;
			dataSources.forEach(d -> readOnlyClients.add(new Sql(d)));
		}
	}

	@Override
	public Sql getSqlClient() {
		Integer index = readOnlyIndex.get();
		Sql client = super.getSqlClient();
		
		do{
			if(index == null) break;
			
			if(CollectionUtils.isEmpty(readOnlyClients) || readOnlyClients.size() - 1 < index){
				log.warn("no readonly sql client was found, use readwrite sql client instead");
				break;	
			}
			
			client = readOnlyClients.get(0);
		}while(false);
		
		return client;
	}

	public Integer getReadOnlyDataSourceIndex(){
		return readOnlyIndex.get();
	}
}
